use crate::errors::{MyError, MyResult};
use crate::utils::config::PROJECT_BASE_PATH;
use std::fs::{remove_file, File, OpenOptions};
use std::io::{Read, Write};
use std::path::PathBuf;

pub fn path_join(path: &str, path1: &str) -> MyResult<String> {
    let mut path_buf = PathBuf::new();
    path_buf.push(path);
    path_buf.push(path1);
    Ok(path_buf
        .to_str()
        .ok_or_else(|| MyError::custom(&format!("路径拼接错误:{},{}", path, path1)))?
        .to_owned())
}
pub fn pwd() -> MyResult<String> {
    Ok(std::env::current_dir()?
        .as_path()
        .to_str()
        .ok_or_else(|| MyError::custom("pwd error"))?
        .to_owned())
}

fn get_project_file(file_path: &str) -> PathBuf {
    let mut buf = PathBuf::from(PROJECT_BASE_PATH);
    buf.push(file_path);
    buf
}

pub fn load_project_file(module_path: &str) -> MyResult<String> {
    let mut file = File::open(get_project_file(module_path))?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    Ok(contents)
}
pub fn write_project_file(module_path: &str, content: &str) -> MyResult<()> {
    let mut file = File::create(get_project_file(module_path))?;
    file.write_all(content.as_bytes())?;
    Ok(())
}
pub fn remove_project_file(module_path: &str) -> MyResult<()> {
    if let Err(e) = remove_file(get_project_file(module_path)) {
        if e.kind() == std::io::ErrorKind::NotFound {
            Ok(())
        } else {
            Err(MyError::IoError(e))
        }
    } else {
        Ok(())
    }
}
pub fn append_project_file(module_path: &str, content: &str) -> MyResult<()> {
    let mut file = OpenOptions::new()
        .create(true)
        .append(true)
        .open(get_project_file(module_path))?;

    file.write_all(content.as_bytes())?;
    Ok(())
}
pub fn init_project_folder(folder_path: &str) -> MyResult<()> {
    let project_folder_path = path_join(PROJECT_BASE_PATH, folder_path)?;

    if let Err(e) = std::fs::create_dir_all(project_folder_path) {
        if e.kind() == std::io::ErrorKind::AlreadyExists {
            Ok(())
        } else {
            Err(MyError::IoError(e))
        }
    } else {
        Ok(())
    }
}
